﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Common.Utilities;

namespace Workflows.Components.Entities.Distances.Comparers
{
    /// <summary>
    /// 
    /// </summary>
    public class TfidfComparer:IAttributeComparer
    {
        public AttributeComparerType ComparerType
        {
            get { return AttributeComparerType.ClassComparer; }
        }

        public SqlDbType FieldDbType
        {
            get { return SqlDbType.NText; }
            set { throw new NotImplementedException(); }
        }

        public double Compare(object value1, object value2, double penalty,
            SqlConnection conn, string termScoreTblName)
        {
            if (conn == null || conn.State != ConnectionState.Open || string.IsNullOrEmpty(termScoreTblName))
                throw new Exception(
                    "Connection must be initialized and term index table must be provided in order to do tfidf search");

            if (value1 == null || value2 == null || value1.ToString().Length == 0 || value2.ToString().Length == 0)
                return 0.0;

            string[] words1 = StringUtil.Split(value1.ToString());
            string[] words2 = StringUtil.Split(value2.ToString());
            string[] commonWords = StringUtil.Intersection(words1, words2);
            double compareScore = 0.0;
            if (commonWords != null && commonWords.Length > 0)
            {
                foreach (string commonWord in commonWords)
                {
                    compareScore += this.GetTermScore(conn, termScoreTblName, commonWord);
                }
            }
            if (compareScore == 0)
                compareScore = penalty;
            return compareScore;
        }

        public object Merge(List<object> values, SqlConnection conn, string unevenDistTableName)
        {
            throw new NotImplementedException();
        }

        private double GetTermScore(SqlConnection conn, string tblName, string term)
        {
            double score = 0.0;
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = string.Format("select {0} from {1} where {2}='{3}'", "Score", tblName, "Term", term);
            SqlDataReader reader = cmd.ExecuteReader();
            if(reader.Read())
            {
                score = reader.GetDouble(0);
            }
            reader.Close();
            return score;
        }
    }
}
